﻿#region Copyright (c) 2000-2013 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2013 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2013 Developer Express Inc.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using DevExpress.Xpf.Core;
using UColor.Core.Helpers;
using System.Collections.ObjectModel;
namespace UColor.WPF.Helpers {
	public enum LoadingSplashBackground { None, White, Black }
	public class ThemeSelectorHelper : DependencyObject {
		static class ThemeManager2 {
			static ThemeManager2() {
#if SL
				ThemeManager.ApplicationThemeChanged += OnThemeManagerThemeChanged;
				ThemeManager.ActualApplicationThemeChanged += new ThemeChangedRoutedEventHandler(OnThemeManagerActualApplicationThemeChanged);
#else
				ThemeManager.ThemeChanged += OnThemeManagerThemeChanged;
#endif
			}
			public static event EventHandler ThemeChanged;
			public static event EventHandler BeginLoading;
			public static event EventHandler EndLoading;
#if SL
			static void OnThemeManagerActualApplicationThemeChanged(DependencyObject d, ThemeChangedRoutedEventArgs e) {
				if(EndLoading != null)
					EndLoading(typeof(ThemeManager2), EventArgs.Empty);
			}
#endif
			static void OnThemeManagerThemeChanged(DependencyObject sender, ThemeChangedRoutedEventArgs e) {
#if !SL
				if(Application.Current != null && !Application.Current.Dispatcher.CheckAccess()) return;
#endif
				if(ThemeChanged != null)
					ThemeChanged(typeof(ThemeManager2), EventArgs.Empty);
#if !SL
				if(EndLoading != null)
					EndLoading(typeof(ThemeManager2), EventArgs.Empty);
#endif
			}
			public static void SelectTheme(string themeName) {
				if(themeName == ThemeManager.ApplicationThemeName) return;
				if(BeginLoading != null)
					BeginLoading(typeof(ThemeManager2), EventArgs.Empty);
				BackgroundHelper.DoInBackground(null, () => {
					ThemeManager.ApplicationThemeName = themeName;
				});
			}
		}
		#region Dependency Properties
		public static readonly DependencyProperty ApplicationThemeProperty;
		public static readonly DependencyProperty LoadingInProgressProperty;
		static ThemeSelectorHelper() {
			Type ownerType = typeof(ThemeSelectorHelper);
			ApplicationThemeProperty = DependencyProperty.Register("ApplicationTheme", typeof(Theme), ownerType, new PropertyMetadata(Theme.Default, RaiseApplicationThemeChanged));
			LoadingInProgressProperty = DependencyProperty.Register("LoadingInProgress", typeof(bool), ownerType, new PropertyMetadata(false));
			InitThemes();
		}
		Theme applicationThemeValue = Theme.Default;
		static void RaiseApplicationThemeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((ThemeSelectorHelper)d).applicationThemeValue = (Theme)e.NewValue;
			((ThemeSelectorHelper)d).RaiseApplicationThemeChanged(e);
		}
		#endregion
		public event ThePropertyChangedEventHandler<Theme> ApplicationThemeChanged;
		WeakEventHandler<EventArgs> onThemeManagerThemeChanged;
		WeakEventHandler<EventArgs> onThemeManagerBeginLoading;
		WeakEventHandler<EventArgs> onThemeManagerEndLoading;
		bool updatingTheme = false;
		static ReadOnlyCollection<Theme> themes;
		public ThemeSelectorHelper() {
			onThemeManagerThemeChanged = new WeakEventHandler<EventArgs>(OnThemeManagerThemeChanged);
			onThemeManagerBeginLoading = new WeakEventHandler<EventArgs>(OnThemeManagerBeginLoading);
			onThemeManagerEndLoading = new WeakEventHandler<EventArgs>(OnThemeManagerEndLoading);
			ThemeManager2.ThemeChanged += onThemeManagerThemeChanged.Handler;
			OnThemeManagerThemeChanged(typeof(ThemeManager2), EventArgs.Empty);
			ThemeManager2.BeginLoading += onThemeManagerBeginLoading.Handler;
			ThemeManager2.EndLoading += onThemeManagerEndLoading.Handler;
		}
		static void InitThemes() {
			themes = new ReadOnlyCollection<Theme>((from theme in Theme.Themes where !theme.Name.Contains("Demo") select theme).ToList().AsReadOnly());
		}
		void OnThemeManagerEndLoading(object sender, EventArgs e) {
			LoadingInProgress = false;
		}
		void OnThemeManagerBeginLoading(object sender, EventArgs e) {
			LoadingInProgress = true;
		}
		public Theme ApplicationTheme { get { return applicationThemeValue; } set { SetValue(ApplicationThemeProperty, value); } }
		public bool LoadingInProgress { get { return (bool)GetValue(LoadingInProgressProperty); } set { SetValue(LoadingInProgressProperty, value); } }
		public ReadOnlyCollection<Theme> Themes { get { return themes; } }
		void OnThemeManagerThemeChanged(object sender, EventArgs e) {
			updatingTheme = true;
			ApplicationTheme = ThemeManager.ApplicationThemeName == null ? null : Theme.FindTheme(ThemeManager.ApplicationThemeName);
			updatingTheme = false;
		}
		void RaiseApplicationThemeChanged(DependencyPropertyChangedEventArgs e) {
			if(updatingTheme) return;
			ThemeManager2.SelectTheme(ApplicationTheme == null ? null : ApplicationTheme.Name);
			if(ApplicationThemeChanged != null)
				ApplicationThemeChanged(this, new ThePropertyChangedEventArgs<Theme>((Theme)e.OldValue, (Theme)e.NewValue));
		}
		public static LoadingSplashBackground ThemeToLoadingSplashBackground(string theme) {
			return theme != null && theme == Theme.MetropolisDarkName ? LoadingSplashBackground.Black : LoadingSplashBackground.White;
		}
	}
}
